#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
/*
 * Copyright © 2014, Finium Sdn Bhd, All Rights Reserved
 * 
 * HibernateNamedQueryUtil.java
 * Modification History
 * *************************************************************
 * Date				Author						Comment
 * Oct 26, 2013		Venkaiah Chowdary Koneru	Created
 * *************************************************************
 */
package ${package}.support.hibernate;

import java.math.BigInteger;
import java.util.List;
import java.util.Map;

import ${package}.dto.ListProp;
import ${package}.entity.AbstractEntity;
import ${package}.support.CommonsUtil;

import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.transform.Transformers;
import org.springframework.util.StringUtils;

/**
 * Utility class to hold Named Query related functionality.
 * 
 * @author Venkaiah Chowdary Koneru
 */
public final class HibernateNamedQueryUtil extends AbstractHibernateQueryUtil
{
    /**
     * Helper method to ease the query process for named queries
     * 
     * @param sessionFactory
     *            must not be null.
     * @param query
     *            must not be blank. Must be the Named query string.
     * @param countQuery
     *            must not be blank. Must be the Named count query string.
     * @param listProp
     *            can be null.
     * @param resultClass
     *            can be null.
     * @param parameters
     *            can be null if no parameter is required.
     * @return List of the result object.
     */
    public static List<?> list(SessionFactory sessionFactory,
            final String query, final String countQuery,
            final ListProp listProp, final Class<?> resultClass,
            final Map<String, Object> parameters)
    {
        if (sessionFactory == null || !StringUtils.hasText(query))
        {
            return null;
        }

        Session session = sessionFactory.getCurrentSession();

        if (StringUtils.hasText(countQuery))
        {
            setCountData(session.getNamedQuery(countQuery), listProp,
                    parameters);
        }

        if (AbstractEntity.class.isAssignableFrom(resultClass))
        {
            SQLQuery namedQuery = (SQLQuery) session.getNamedQuery(query);

            namedQuery = session.createSQLQuery(namedQuery.getQueryString()
                    + generateSorting(listProp, null));

            namedQuery.addEntity(resultClass);

            setParameters(parameters, namedQuery);

            setPagination(listProp, namedQuery);

            return namedQuery.list();
        }
        else
        {
            Query namedQuery = session.getNamedQuery(query);

            namedQuery = session.createSQLQuery(namedQuery.getQueryString()
                    + generateSorting(listProp, null));

            namedQuery.setResultTransformer(Transformers
                    .aliasToBean(resultClass));

            setParameters(parameters, namedQuery);

            setPagination(listProp, namedQuery);

            return namedQuery.list();
        }
    }

    /**
     * Executes the Count query and sets the total records property value of
     * list prop.
     * 
     * @param countQuery
     *            count query. this should not be empty.
     * @param listProp
     *            list prop object
     * @param parameters
     *            parameters
     */
    private static void setCountData(Query countQuery, ListProp listProp,
            Map<String, Object> parameters)
    {
        if (countQuery != null && listProp != null
                && listProp.getStartIndex() >= getStartIndex())
        {
            setParameters(parameters, countQuery);

            List<?> countList = countQuery.list();
            if (CommonsUtil.isEmpty(countList))
            {
                listProp.setTotalRecords(0);
            }
            else
            {
                listProp.setTotalRecords(((BigInteger) countList.iterator()
                        .next()).longValue());
            }
        }
    }

    /**
     * Constructor. private to prevent unnecessary instantiation.
     */
    private HibernateNamedQueryUtil()
    {
    }
}
